package dm.ast;

import test.envset.GlobalState;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * DM的表或视图
 * 数据库中可用的表或者视图
 * 来源与元数据信息，不包含子查询、中间表等
 * 处于AST中的叶子节点
 */
public class DmTable extends DmTableSource{
    //元数据信息
    //分区子表名
    private ArrayList<String> subTabs = null;
    //标志为视图或者表 true表示为表 false表示为视图
    private Boolean tag = null;
    //表属性
    private HashMap<String , String> attris;  //目前支持pk(主键)

    //AST信息
    public Boolean subTabFlag = false;  //是否启用分区表查询，一般用于语句生成
    public String subTab = null;  //所用到的分区子表名

    public DmTable() {
        isSubSelect = false;
        isCompleted = false;
        isLeaf = true;
    }

    public DmTable(String name) {
        this.name = name;
        isCompleted = false;
        isLeaf = true;
        alias = null;
        // TODO: 2024/4/11  ???
    }

    public void setTag(String type){
        if(type.equals("VIEW")){
            tag = false;
        }else {
            tag = true;
        }
    }

    //是否是分区表
    public boolean isPartitioned(){
        if(subTabs == null){
            return false;
        }else {
            return true;
        }
    }

    public synchronized void addSubTab(String subname){
        if(subTabs == null){
            subTabs = new ArrayList<String>();

        }
        subTabs.add(subname);
    }

    public ArrayList<String> getSubTabs(){
        return subTabs;
    }

    public void setWidt(){
        wid_t = 1;
    }

    public void setDept(){
        dep_t = 1;
    }

    public DmDataType getExpressionType(){
        return null;
    }

    public void addColumn(DmColumn col){
        if(cols == null){
            this.cols = new ArrayList<DmColumn>();
        }
        DmColumn tmp = new DmColumn(col.name , col.type);
        tmp.tableName = getSelectName();
        this.cols.add(tmp);
    }

    public String toSql(){
        if(name == null){
            return " " + this.getClass().getSimpleName();
        }else if(alias == null){
            if(subTab != null){
                return getFullName() + " PARTITION ( " + subTab + " ) ";

            }else {
                return getFullName();
            }
        }else {
            return getFullName() + " AS " + alias;
        }
    }

    public void fill(GlobalState globalState){
        if(!isCompleted){
            //填充步骤
            //1、随机选取一个表T1
            //2、需要判断T1是否已经使用，如果已经使用，需要设置别名
            //3、通过T1填充
            DmTable tab = globalState.getRanDmTableFromRepo();
            if(globalState.tableUesd(tab)){
                this.setAlias(globalState.tabAlias());
            }
            fillByTable(tab);
            fillASTpartition(globalState,tab);
            isCompleted = true;
        }
    }

    //通过表填充
    public void fillByTable(DmTable tab){
        this.name = tab.name;
        this.schemaOf = tab.schemaOf;
        this.cols = new ArrayList<DmColumn>();
        for(DmColumn tmp : tab.cols){
            addColumn(tmp);
        }
        isCompleted = true;
    }

    //设置AST所用分区子表信息
    public void fillASTpartition(GlobalState globalState , DmTable tab){
        if(subTabFlag == true && tab.isPartitioned()){
            this.subTab = globalState.getRanSub(tab);
        }
    }

    //构造一个虚拟表，包含表名和列信息
    //这样可以用于临时保存with子句中的CTE，便于进行填充处理
    public static DmTable buildVirtualTable(String tabName , List<DmColumn> cols){
        DmTable virTab = new DmTable(tabName);
        virTab.cols = cols;
        return virTab;
    }
}
